home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CUCD / Graphics / STIMP_noise / source / pnmaddnoise / pnmaddnoise.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  4.5 KB  |  179 lines

  1.  
  2. /************************************************************************/
  3. #define OP_NAME      "pnmaddnoise"
  4. #define VERSION      "1.02"
  5. #define DATE         "31.01.98"
  6. #define AUTHOR       "Stefan Diener"
  7. /************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <stdarg.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <math.h>
  14. #include <time.h>
  15. #include <sys/types.h>
  16.  
  17. #include <STIMP/pnm.c>
  18.  
  19. struct PNM_Info bild;
  20. static float Prozent=5.0;
  21. static float Gewicht=0.2;
  22.  
  23. void Do_It(void)
  24. {
  25.   int i, j, ende, diff, temp;
  26.   int x=0, y=0, bx, by;
  27.   unsigned char *dstR, *dstG, *dstB;
  28.  
  29.   const int ax=65;
  30.   const int ay=17;
  31.  
  32.   /* Zeiger auf Bilddaten holen */
  33.   if (bild.type==TYPE_PPM)
  34.   {
  35.     dstR=bild.redDATA;
  36.     dstG=bild.greenDATA;
  37.     dstB=bild.blueDATA;
  38.   }
  39.   else dstR=bild.DATA;
  40.  
  41.   /* Zahl der zu veraendernden Punkte */
  42.   ende=(int) floor(bild.width*bild.height*Prozent/100.0);
  43.  
  44.   /* neue Folge von Zufallszahlen erzeugen */
  45.   srand((unsigned)time(NULL));
  46.  
  47.   /* Ansatz: Methode der linearen Kongruenzen */
  48.   /* Problem: ggt(bx,source.width) muesste 1 sein */
  49.   /* und ggt(by,source.height) ebenfalls 1 */
  50.   /* hier: Ausbuegeln der kleineren Periode und der */
  51.   /* ev. sichtbaren Muster durch Zufallsanteil */
  52.   bx=3*bild.width/4+1;
  53.   by=bild.height/2+1;
  54.  
  55.   /* nur Prozentsatz der Punkte veraendern */
  56.   for (j=0; j<ende; j++)
  57.   {
  58.     /* lin. Kongruenzen und Zufallsanteil */
  59.     x=(ax*x+bx+(int) floor(50.0-100.0*((double) rand()/(double)RAND_MAX)))%bild.width;
  60.     y=(ay*y+by+(int) floor(50.0-100.0*((double) rand()/(double)RAND_MAX)))%bild.height;
  61.  
  62.     /* Koordinate des Bildpunktes */
  63.     i=y*bild.width+x;
  64.  
  65.     /* roten Anteil verrauschen */
  66.     diff=(int) floor(256*((double)rand()/(double)RAND_MAX));
  67.     temp=(int) floor(Gewicht*diff+(1.0-Gewicht)*dstR[i]);
  68.     dstR[i]=(temp<bild.maxval) ? temp : bild.maxval;
  69.  
  70.     if (bild.type==TYPE_PPM)
  71.     {
  72.       /* gruenen Anteil verrauschen */
  73.       diff=(int) floor(256*((double)rand()/(double)RAND_MAX));
  74.       temp=(int) floor(Gewicht*diff+(1.0-Gewicht)*dstG[i]);
  75.       dstG[i]=(temp<bild.maxval) ? temp : bild.maxval;
  76.  
  77.       /* blauen Anteil verrauschen */
  78.       diff=(int) floor(256*((double)rand()/(double)RAND_MAX));
  79.       temp=(int) floor(Gewicht*diff+(1.0-Gewicht)*dstB[i]);
  80.       dstB[i]=(temp<bild.maxval) ? temp : bild.maxval;
  81.     }
  82.    }
  83. }
  84.  
  85. int main(int argc,char **argv)
  86. /* Hauptprogramm */
  87. {
  88.   int i;
  89.   unsigned char tempo[10];
  90.  
  91.   /* offizielle Begruessung */
  92.   PrintOpening(argc,argv);
  93.  
  94.   /* Uebergebene Parameter auswerten */
  95.   for (i=1; i<argc; i++)
  96.   {
  97.     if ((argv[i][0]=='-') && argv[i][1])
  98.     {
  99.       switch (argv[i][1])
  100.       {
  101.         case 'w': strncpy(tempo, argv[i], 9);
  102.                       tempo[0]=32;
  103.                       tempo[1]=32;
  104.                       if (sscanf(tempo,"%f",&Gewicht)!=1) Gewicht=-1.0;
  105.                       if ((Gewicht<0.0) || (Gewicht>1.0))
  106.                       {
  107.                         PrintMessage("Wrong value of the noise weight !");
  108.                         Hilfe();
  109.                         exit(-1);
  110.                       }
  111.                       break;
  112.  
  113.         case 'p': strncpy(tempo, argv[i], 9);
  114.                       tempo[0]=32;
  115.                       tempo[1]=32;
  116.                       if (sscanf(tempo,"%f",&Prozent)!=1) Prozent=0.0;
  117.                       if ((Prozent<=0.0) || (Prozent>100.0))
  118.                       {
  119.                         PrintMessage("Wrong percentage !");
  120.                         Hilfe();
  121.                         exit(-1);
  122.                       }
  123.                       break;
  124.  
  125.         case 'v': beVerbose=FALSE;
  126.                       break;
  127.  
  128.         default: PrintMessage("Unknown parameter: %s", argv[i]);
  129.                      Hilfe();
  130.                      exit(-1);
  131.                      break;
  132.       }
  133.     }
  134.  
  135.     if (argv[i][0]=='+')
  136.     {
  137.       switch (argv[i][1])
  138.       {
  139.         case 'v': beVerbose=TRUE;
  140.                       break;
  141.  
  142.         default: PrintMessage("Unknown parameter: %s", argv[i]);
  143.                      Hilfe();
  144.                      exit(-1);
  145.                      break;
  146.       }
  147.     }
  148.   }
  149.  
  150.   /* Mindestzahl der Argumente pruefen */
  151.   if (argc<3)
  152.   {
  153.     PrintMessage("Wrong number of arguments !");
  154.     Hilfe();
  155.     exit(-1);
  156.   }
  157.  
  158.   /* Anzahl der Dateinamen überprüfen */
  159.   if (FilenameCount(argc, argv)!=2)
  160.   {
  161.     PrintMessage("Wrong number of file names !");
  162.     Hilfe();
  163.     exit(-1);
  164.   }
  165.  
  166.   if (ReadPNMFile(GetFilename(1,argc,argv), TYPE_PNM, &bild)==0)
  167.   {
  168.     PrintMessage("Working ...");
  169.     Do_It();
  170.  
  171.     WritePNMFile(GetFilename(2,argc,argv),&bild);
  172.     FreePNMArray(&bild);
  173.   }
  174.  
  175.   PrintClosing();
  176.   exit(0);
  177. }
  178.  
  179.